import json
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                            QHBoxLayout, QGridLayout, QLabel, QLineEdit, QPushButton, QComboBox, QTextEdit, QSizePolicy)
from PyQt5.QtCore import Qt, pyqtSlot

class uuh_windows(QMainWindow):
    def __init__(self, json_path):
        super().__init__()
        self.widget_map = {}
        self.layout_stack = []
        self.load_config(json_path)
        
    def load_config(self, json_path):
        """加载JSON配置文件"""
        with open(json_path, 'r', encoding='utf-8') as f:
            config = json.load(f)
            
        # 初始化主窗口
        self.setWindowTitle(config.get('title', 'default title'))
        self.resize(config.get('width', 800), config.get('height', 600))
        
        # 创建中心部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        self._parse_layout(config['layout'], central_widget)
    
    def _parse_layout(self, config, parent):
        """递归解析布局配置"""
        # 创建布局对象
        layout_map = {
            'vbox': QVBoxLayout,
            'hbox': QHBoxLayout,
            'grid': QGridLayout
        }
        
        if config['type'] in layout_map:
            layout = layout_map[config['type']]()

            parent.setLayout(layout)
            self.layout_stack.append(layout)
            
            # 设置对齐方式
            if not config.get('alignment') is None:
                layout.setAlignment(self._parse_alignment(config['alignment']))

            # 处理布局间距
            if 'spacing' in config:
                layout.setSpacing(config['spacing'])
                
            # 处理内容边距
            margins = config.get('margins', [0,0,0,0])
            layout.setContentsMargins(*margins)
            

            # 递归处理子元素
            for item in config.get('children', []):
                if 'type' in item and item['type'] in layout_map:
                    container = QWidget()
                    layout.addWidget(container)
                    self._parse_layout(item, container)
                else:
                    self._create_widget(item, parent)
            
            self.layout_stack.pop()
        else:
            self._create_widget(config, parent)
    
    def _create_widget(self, config, parent):
        """创建具体控件"""
        widget = None
        widget_type = config['type'].lower()
        
        # 创建基础控件
        if widget_type == 'label':
            widget = QLabel(config.get('text', ''), parent)
            if 'alignment' in config:
                widget.setAlignment(self._parse_alignment(config['alignment']))
        elif widget_type == 'lineedit':
            widget = QLineEdit(parent)
            widget.setPlaceholderText(config.get('placeholder', ''))
            if 'maxLength' in config:
                widget.setMaxLength(config['maxLength'])
        elif widget_type == 'button':
            widget = QPushButton(config.get('text', ''), parent)
            if 'onClick' in config:
                widget.clicked.connect(lambda: self._call_slot(config['onClick']))
        elif widget_type == 'combo':
            widget = QComboBox(parent)
            if config.get('items') is not None:
                widget.addItems(config.get("items", []))  # 长列表导致控件自动扩展
        elif widget_type == 'textedit':
            widget = QTextEdit(parent)
            widget.setPlaceholderText(config.get('placeholder', ''))

        # 设置通用属性
        if widget:
            if 'name' in config:
                self.widget_map[config['name']] = widget
            if 'style' in config:
                widget.setStyleSheet(config['style'])
            if 'visible' in config:
                widget.setVisible(config['visible'])
            if 'width' in config:
                widget.setMinimumWidth(config['width'])
            if 'policy' in config:
                policy = self._parse_policy(config.get('policy', 'fixed'))
                widget.setSizePolicy(policy, QSizePolicy.Preferred)
        
            # 添加到当前布局
            if self.layout_stack:
                self._add_to_layout(widget, config)
    
    def _add_to_layout(self, widget, config):
        """将控件添加到布局"""
        current_layout = self.layout_stack[-1]
        
        if isinstance(current_layout, QGridLayout):
            position = config.get('position', [0, 0])
            span = config.get('span', [1, 1])
            current_layout.addWidget(widget, 
                                   position[0], position[1],
                                   span[0], span[1])
        else:
            stretch = config.get('stretch', 0)
            alignment = self._parse_alignment(config.get('alignment', 'left'))
            current_layout.addWidget(widget, stretch, alignment)
    
    def _parse_alignment(self, align_str):
        """解析对齐方式字符串"""
        align_map = {
            'left': Qt.AlignLeft,
            'right': Qt.AlignRight,
            'center': Qt.AlignCenter,
            'top': Qt.AlignTop,
            'bottom': Qt.AlignBottom,
            'hcenter': Qt.AlignHCenter,
            'vcenter': Qt.AlignVCenter
        }
        return align_map.get(align_str.lower(), Qt.AlignLeft)
    
    def _parse_policy(self, policy_str):
        """解析尺寸策略字符串"""
        policy_map = {
            'fixed': QSizePolicy.Fixed,
            'min': QSizePolicy.Minimum,
            'max': QSizePolicy.Maximum,
            'pref': QSizePolicy.Preferred,
            'min_ex': QSizePolicy.MinimumExpanding,
            'expanding': QSizePolicy.Expanding,
            'ignored': QSizePolicy.Ignored
        }
        return policy_map.get(policy_str.lower(), QSizePolicy.Ignored)
    
    def _call_slot(self, slot_name):
        """动态调用槽函数"""
        if hasattr(self, slot_name):
            getattr(self, slot_name)()
        else:
            print(f"未实现的槽函数: {slot_name}")